﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;

namespace voha_test_1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private static readonly int[] AllowedKeys = {1, 3, 8, 22, 24, 26};
        private readonly Dictionary<byte, double> _quatersNum = new Dictionary<byte, double>
        {
            {1, 0},
            {2, 0},
            {3, 0},
            {4, 0}
        };

        private void CalcTaxData(byte qNum, object sender, TextBox tbTotal, TextBox tbTotal5, TextBox tbTax)
        {
            var tbQ = (TextBox)sender;
            double q = TryConvertToFloat(tbQ.Text, tbQ);
            _quatersNum[qNum] = q;
            if (q == -1)
            {
                const string inputErr = "Error";
                tbTotal.Text = tbTotal5.Text = tbTax.Text = inputErr;
                return;
            }
            double total = Math.Round(GetSumQ(qNum), 2);
            double total5 = Math.Round(total * 0.05, 2);
            double tax = Math.Round(q * 0.05, 2);
            tbTotal.Text = total.ToString().Replace(',','.');
            tbTotal5.Text = total5.ToString().Replace(',', '.');
            tbTax.Text = tax.ToString().Replace(',', '.');
            TrailingZeros(tbTotal);
            TrailingZeros(tbTotal5);
            TrailingZeros(tbTax);
        }

        private static double TryConvertToFloat(string str, TextBox tb = null)
        {
            double f;
            try
            {
                f = ParseToDouble(str);
                if (tb != null && tb.BackColor == Color.Red)
                    tb.BackColor = Color.White;
            }
            catch (Exception)
            {
                f = -1;
            }

            if (f == -1 && tb != null && tb.Text.Length != 0)
            {
                tb.BackColor = Color.Red;
            }
            return f;
        }

        private static double ParseToDouble(string str)
        {
            var arr = str.Split('.');
            if (arr.Length > 2)
                return -1;
            long num1;
            if (!long.TryParse(arr[0], out num1))
                return -1;
            double f = arr[0].Length == 0 ? 0 : num1;
            if (arr.Length == 2 && arr[1].Length > 0)
            {
                long num2;
                if (!long.TryParse(arr[1], out num2))
                    return -1;
                f = f + num2 * Math.Pow(10, -arr[1].Length);
            }

            return f;
        }

        private static void AddZeros(object sender)
        {
            var tb = (TextBox)sender;
            if (tb.Text.IndexOf(".") == 0)
            {
                tb.Text = @"0" + tb.Text;
                tb.Select(tb.Text.Length, 0);
            }
        }

        private static void RestrictInput(object sender, KeyPressEventArgs e)
        {
            var tb = (TextBox) sender;
            if (Char.IsDigit(e.KeyChar) || e.KeyChar == '.' && (tb.Text.IndexOf(".") == -1 || tb.SelectedText == tb.Text))
                return;

            if (!AllowedKeys.Contains(e.KeyChar))
            {
                e.Handled = true;
            }
        }

        private double GetSumQ(byte q)
        {
            double sum = 0;
            for (byte i = 1; i <= q; i++)
            {
                if (_quatersNum[i] == -1)
                    return 0;
                sum += _quatersNum[i];
            }

            return sum;
        }

        private static void TrailingZeros(object sender)
        {
            var tb = (TextBox) sender;

            if (!tb.Text.Contains("."))
            {
                tb.Text += ".";
            }
            var arr = tb.Text.Split('.');
            if (arr.Length == 1)
            {
                tb.Text += @"00";
            }
            else if (arr.Length == 2)
            {
                if (arr[1].Length == 0)
                    tb.Text += @"00";
                else if (arr[1].Length == 1)
                    tb.Text += @"0";
            }
            else //fuck Vova's mind
            {
                tb.Visible = false;
                tb.ReadOnly = true;
            }
        }

        private void RoundNumber(object sender)
        {
            var tb = (TextBox)sender;
            var q = WhichQuater(sender);
            if (_quatersNum[q] == -1)
                return;
            _quatersNum[q] = Math.Round(_quatersNum[q], 2);
            tb.Text = _quatersNum[q].ToString().Replace(',', '.');
            tb.Update();
        }

        private static byte WhichQuater(object sender)
        {
            var tb = (TextBox)sender;
            byte q;
            if (tb.Name.Contains("1"))
                q = 1;
            else if (tb.Name.Contains("2"))
                q = 2;
            else if (tb.Name.Contains("3"))
                q = 3;
            else
                q = 4;
            return q;
        }

        private void TbQ1_TextChanged(object sender, EventArgs e)
        {
            AddZeros(sender);
            CalcTaxData(1, sender, TbQ1Total, TbQ1Total5, TbQ1Tax);
            TbQ2_TextChanged(TbQ2, e);
        }

        private void TbQ2_TextChanged(object sender, EventArgs e)
        {
            AddZeros(sender);
            CalcTaxData(2, sender, TbQ2Total, TbQ2Total5, TbQ2Tax);
            TbQ3_TextChanged(TbQ3, e);
        }

        private void TbQ3_TextChanged(object sender, EventArgs e)
        {
            AddZeros(sender);
            CalcTaxData(3, sender, TbQ3Total, TbQ3Total5, TbQ3Tax);
            TbQ4_TextChanged(TbQ4, e);
        }

        private void TbQ4_TextChanged(object sender, EventArgs e)
        {
            AddZeros(sender);
            CalcTaxData(4, sender, TbQ4Total, TbQ4Total5, TbQ4Tax);
        }

        private void TbQ1_KeyPress(object sender, KeyPressEventArgs e)
        {
            RestrictInput(sender, e);
        }

        private void TbQ4_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == 0x09)
            {
                TbQ1.Focus();
                e.Handled = true;
                return;
            }
            RestrictInput(sender, e);
        }

        private void TbQ2_KeyPress(object sender, KeyPressEventArgs e)
        {
            RestrictInput(sender, e);
        }

        private void TbQ3_KeyPress(object sender, KeyPressEventArgs e)
        {
            RestrictInput(sender, e);
        }

        private void TbQ1_Leave(object sender, EventArgs e)
        {
            RoundNumber(sender);
            TrailingZeros(sender);
        }

        private void TbQ2_Leave(object sender, EventArgs e)
        {
            RoundNumber(sender);
            TrailingZeros(sender);
        }

        private void TbQ3_Leave(object sender, EventArgs e)
        {
            RoundNumber(sender);
            TrailingZeros(sender);
        }

        private void TbQ4_Leave(object sender, EventArgs e)
        {
            RoundNumber(sender);
            TrailingZeros(sender);
        }
    }
}
